home *** CD-ROM | disk | FTP | other *** search
- /*
- MoveMouse.c
-
- (This is from Apple. It may be useful to people who need
- an equivalent to SetMouse.c that works on the Centris
- Macs. Unfortunately it can't be compiled to native code
- for PowerPC. Most people should stick to the current
- SetMouse.c and ignore this file and the Cursor Device
- Manager until Apple provides us with a truly general
- interface that works on ALL Macs. - dgp, 10/94
-
- NOTE: The THINK C 6 compiler chokes on the (legal) recursive structure
- definition at line 86. The THINK C 7 and CodeWarrior compilers don't
- complain.)
-
- From Apple Developer Services:
-
- In the past, moving the cursor programatically on the Macintosh has
- entailed the manipulation of low memory globals. This has worked for
- all macs for quite some time. But with the advent of the power book
- series and many 3rd party track balls, it has become apparent that the
- low memory globals no longer contained adequate information for the
- system to truly support all types of positioning devices. So, with the
- new Centris CPU's, and CPU's from all lines after we are implementing a
- new tool set that provides a much more comprehensive set of utilities
- for dealing with the cursor location and mouse button state. We call
- this new manager the Cursor Device Manager, and DTS will be documenting
- it in a future tech not, but since many machines are now shipping that
- do not use the traditional low memory globals to get the mouse location
- and position the mouse, it is important to "leak" a little of the tech
- note information early.
-
- First, the CDM (Cursor device manager) has its own trap ($AADB) and you
- can determine if a machine supports the CDM by using the standard trap
- Available routine. (See inside mac for the source code to Trap
- Available). Once you have determined that the CDM exists, you should
- try not to use the low memory globals RawMouse and MTemp to get the
- current cursor location, or set a new cursor location. Instead the CDM
- provides 3 calls which you can use to get this info, the first is
- CrsrDevNextDevice which will give you the next cursor device record in
- the CDM list, if you pass it a NULL, it will give you the head of the
- list. Once you have the first cursor device you can use it to get the
- Cursor data record which contains the current cursor location in its
- where field. You can set the current location with either the
- CrsrDevMove (which moves relative to the current location) or the
- CrsrDevMoveTo (which moves to an absolute location) routines.
-
- The following is some sample code which implement some generic routines
- that work on all macintoshes. These routines are written not for speed
- but for clarity, so if you are writing a device driver or time critical
- code there are some things that you can do to speed up these routines,
- like predetermine at the outset if the CDM exists, this way you
- wouldn't have to check every time you want to use it, an d getting the
- cursor device only once and keeping the pointer to it around between
- calls.
-
- Anyway, here is some sample code that moves the mouse diagonally until
- the mouse button is pressed. For a further explanation of how the older
- low memory global method works, see the developer support tech info
- database on AppleLink.
-
- NOTE: Despite all the above claims to providing a general solution,
- in fact this code is 680x0-specific, and can't be compiled to run
- native on PowerPC. So I'm not planning on using the Cursor Device
- Manager until Apple provides a platform-independent calling interface.
-
- HISTORY:
- 8/94 dgp Downloaded from ftp://nada.kth.se/pub/hacks/mac-faq/MoveMouse.c
- 10/94 dgp made minimal changes so that it would compile in CodeWarrior C. Still untested.
- */
-
- #if __powerc
- #error "This file cannot be compiled as PowerPC native code."
- #else
- #include "VideoToolbox.h" // TrapAvailable
- #include <Quickdraw.h>
-
- // These are some temporary headers to use with CDM until we come out with
- // the real interfaces. DO NOT count on the field names and call names to
- // remain the same in the released interfaces, this is strictly advanced info
- // which is a best guess.
- struct CrsrDataRec {
- struct CrsrDataRec *nextCrsrData; // Linked list ptr to next one
- Ptr displayInfo; // Future expansion
- Fixed whereX; // fixed point cursor location
- Fixed whereY;
- Point where; // QD cursor location
- Boolean isAbs; // true if the coords last used were absolute
- char ButtonCount; // number of buttons currently pressed
- short ScreenRes; //pixels per inch on current screen
- };
-
- typedef struct CrsrDataRec CrsrDataRec;
-
- struct CrsrDevRec {
- struct CrsrDevRec *nextCrsrDev; // linked list ptr to next device
- CrsrDataRec *whichCursor; // cursor data associated with device
- long refCon; // device specific data
- long unused; // reserved internal use
- OSType devID; // See future tech note for desc
- Fixed resolution; // See future tech note for desc
- char devClass; // See future tech note for desc
- char cntButtons; // See future tech note for desc
- char spare1; // See future tech note for desc
- char buttons; // See future tech note for desc
- char buttonOp[8]; // See future tech note for desc
- long buttonTicks[8]; // See future tech note for desc
- long buttonData[8]; // See future tech note for desc
- long doubleClickTime; // See future tech note for desc
- Fixed acceleration; // See future tech note for desc
- Ptr accelPoints; // See future tech note for desc
- Fixed deltaX; // See future tech note for desc
- Fixed deltaY; // See future tech note for desc
- Fixed errorX; // See future tech note for desc
- Fixed errorY; // See future tech note for desc
- Fixed denom; // See future tech note for desc
- Fixed spread; // See future tech note for desc
- char newData; // See future tech note for desc
- char spare2; // See future tech note for desc
- };
- typedef struct CrsrDevRec CrsrDevRec;
-
- pascal OSErr CrsrDevMove(CrsrDevRec *ourDevice,long deltaX,long deltaY) =
- {0x303C,0x0000,0xAADB}; // Move cursor relative
- pascal OSErr CrsrDevMoveTo(CrsrDevRec *ourDevice,long absX,long absY) =
- {0x303C,0x0001,0xAADB}; // Move cursor absolute
- pascal OSErr CrsrDevFlush(CrsrDevRec *ourDevice) = {0x303C,0x0002,0xAADB};
- // flush the device cause its idle (dump accumulated error stuff
- pascal OSErr CrsrDevButtons(CrsrDevRec *ourDevice,char buttons) = {0x303C,
- 0x0003,0xAADB}; // See future tech note for desc
- pascal OSErr CrsrDevButtonDown(CrsrDevRec *ourDevice) = {0x303C,0x0004,0xAADB};
- // See future tech note for desc
- pascal OSErr CrsrDevButtonUp(CrsrDevRec *ourDevice) = {0x303C,0x0005,0xAADB};
- // See future tech note for desc
- pascal OSErr CrsrDevButtonOp(CrsrDevRec *ourDevice) = {0x303C,0x0006,0xAADB};
- // See future tech note for desc
- pascal OSErr CrsrDevSetButtons(CrsrDevRec *ourDevice) = {0x303C,0x0007,0xAADB};
- // See future tech note for desc
- pascal OSErr CrsrDevSetAcceleration(CrsrDevRec *ourDevice) = {0x303C,0x0008,
- 0xAADB}; // See future tech note for desc
- pascal OSErr CrsrDevDoubleTime(CrsrDevRec *ourDevice) = {0x303C,0x0009,0xAADB};
- // See future tech note for desc
- pascal OSErr CrsrDevUnitsPerInch(CrsrDevRec *ourDevice) = {0x303C,0x000A,
- 0xAADB}; // See future tech note for desc
- pascal OSErr CrsrDevNextDevice(CrsrDevRec **ourDevice) = {0x303C,0x000B,
- 0xAADB}; // obtains the next device in the list
- pascal OSErr CrsrDevNewDevice(CrsrDevRec **ourDevice) = {0x303C,0x000C,0xAADB};
- // See future tech note for desc
- pascal OSErr CrsrDevDisposeDevice(CrsrDevRec *ourDevice) = {0x303C,0x000D,
- 0xAADB}; // See future tech note for desc
-
- pascal void CallCrsr(void) = {0x2078,0x08EE,0x4E90};
- /* that is MOVE.L jCrsrTask,A0
- JSR (A0)
- */
- // Old style mouse moving equates for the low memory globals
- #define xRawMouse 0x082C // low memory global that has current mouse loc
- #define xMTemp 0x0828 // low memory global that has current mouse loc
- #define xCrsrNew 0x08CE // set after you change mtemp and rawmouse
- #define xCrsrCouple 0x08CF // true if the cursor is tied to the mouse
-
- #define _CrsrDevDispatch 0xAADB // new cursor device manager trap
-
- void GetMouseDevPosn(Point *currentPoint);
- void GetMouseDevPosn(Point *currentPoint)
- {
- // This routine returns the current cursor location
- CrsrDevRec *firstMouse;
- if (TrapAvailable(_CrsrDevDispatch)) {
- // If we get here we have the CDM
- firstMouse = NULL; // start at head of cursor dev list
- CrsrDevNextDevice(&firstMouse); // get the next cursor device
- // Now get the current cursor location from the Cursor data
- *currentPoint = firstMouse->whichCursor->where;
- } else {
- // No CDM so we use the low memory global
- *currentPoint = *(Point *)xRawMouse;
- }
- }
-
- void SetMouseDevPosn(Point newPoint);
- void SetMouseDevPosn(Point newPoint)
- {
- // This routine sets the mouse position to the passed point
- CrsrDevRec *firstMouse;
-
- if (TrapAvailable(_CrsrDevDispatch)) {
- // If we get here we have the CDM
- firstMouse = NULL; // start at head of cursor dev list
- CrsrDevNextDevice(&firstMouse); // get the next cursor device
- // Call CDM to move the mouse
- CrsrDevMoveTo(firstMouse,(long)newPoint.h,(long)newPoint.v);
- } else {
- // No CDM so we use the low memory globals
- *(Point *)xRawMouse = newPoint;
- *(Point *)xMTemp = newPoint;
- *(Ptr)xCrsrNew = *(Ptr)xCrsrCouple; // Set CrsrNew if coupled
- CallCrsr(); // must call jCrsrTask to update system
- }
- }
-
- void SetMouseDevPosnRel(Point newPoint);
- void SetMouseDevPosnRel(Point newPoint)
- {
- // Adds the passed point to the current mouse location
- CrsrDevRec *firstMouse;
- Point tempPt;
- if (TrapAvailable(_CrsrDevDispatch)) {
- // If we get here we have the CDM
- firstMouse = NULL; // start at head of cursor dev list
- CrsrDevNextDevice(&firstMouse); // get the next cursor device
- // Call CDM to move the mouse relative
- CrsrDevMove(firstMouse,(long)newPoint.h,(long)newPoint.v);
- } else {
- // No CDM so we use the low memory globals
- tempPt = *(Point *)xRawMouse;
- tempPt.h += newPoint.h;
- tempPt.v += newPoint.v;
- *(Point *)xRawMouse = tempPt;
- *(Point *)xMTemp = tempPt;
- *(Ptr)xCrsrNew = *(Ptr)xCrsrCouple;
- CallCrsr();
- }
- }
-
- void FudgeCursor(void);
- void FudgeCursor(void)
- {
- // Now here is a routine that you can drop into the traffic light sample that
- // can be called to slowly move the mouse to the lower right hand corner of
- // the screen it exits when the mouse button is held down
-
- Point RandPt;
- long fred;
-
- GetMouseDevPosn(&RandPt);
- do {
- RandPt.h += 1; // Bump to the next pixel across
- RandPt.v += 1; // Bump to the next pixel down
-
- SetMouseDevPosn(RandPt); // move absolute
-
- Delay(10,&fred); // wait 10 ticks for smooth drawing
- } while (!Button()); // quit when the button is down.
- }
-
- #endif // !__powerc